package com.game.logic.ranking;

import com.coment.enums.RankingType;
import com.coment.cfg.luban.Tables;
import com.coment.game.core.GameLogic;
import com.coment.po.roles.Roles;
import com.game.logic.core.ranking.RakingService;
import com.game.logic.roles.RolesCultivateLogic;
import com.game.dao.user.roles.RolesDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;

/// 游戏内排行榜
@Slf4j
@Service
public class GameRakingService {
    private final RakingService<Integer> service;
    private final RolesDao rolesDao;

    public GameRakingService(
            RedisTemplate<String, Integer> redisTemplate,
            RolesDao rolesDao
    ) {
        this.service = new RakingService<>(redisTemplate);
        this.rolesDao = rolesDao;
    }

    /// 初始化-玩家榜单
    public void initialize(Integer anchorInfoId, Integer userInfoId, String rolesId) {
        Roles roles = rolesDao.findByIdMust(rolesId);
        service.addLine(GameLogic.getKey(anchorInfoId), RankingType.GAME_CONTRIBUTION, userInfoId, 0D);
        service.addLine(
                GameLogic.getKey(anchorInfoId),
                RankingType.combatEffectiveness,
                userInfoId, RolesCultivateLogic.tryCountFightingCapacity(roles));
    }


    /// 属性战力榜
    public void refreshTheRankingOfInternalCombatPower(Integer anchorInfoId, Roles roles) {
        double fightingCapacity = RolesCultivateLogic.tryCountFightingCapacity(roles);
        String key = GameLogic.getKey(anchorInfoId);
        Integer userInfoId = roles.getUserInfoId();
        this.service.addLine(key, RankingType.combatEffectiveness, userInfoId, fightingCapacity);
    }

    /// 贡献度/s = 战力 * 贡献度(CombatPowerE)
    private final double CombatPowerE = Tables.cfg.get_tbaveragerevenueperusercfg().data().value1;

    /// 刷新贡献榜
    public void refreshTheInternalContributionRankingList(Integer anchorInfoId, Roles roles) {
        double fightingCapacity = RolesCultivateLogic.tryCountFightingCapacity(roles);
        String key = GameLogic.getKey(anchorInfoId);
        Integer userInfoId = roles.getUserInfoId();
        double arp = fightingCapacity * CombatPowerE;
        this.service.addAndIncrementScore(key, RankingType.GAME_CONTRIBUTION, userInfoId, arp);
    }

    /// 增加贡献
    public void addContribution(Integer anchorInfoId, Integer userInfoId, double contribution) {
        this.service.addAndIncrementScore(GameLogic.getKey(anchorInfoId), RankingType.GAME_CONTRIBUTION, userInfoId, contribution);
    }


    /// 获得贡献排名
    public RankingMessage<Integer> obtainContributionRanking(@NotNull Integer anchorInfoId) {
        return new RankingMessage<>(
                RankingType.GAME_CONTRIBUTION.getValue(),
                this.service.reverseRangeWithScores(GameLogic.getKey(anchorInfoId), RankingType.GAME_CONTRIBUTION)
        );
    }
    public List<RakingService.RankInfo<Object>> getAllContributionRRankInfo(@NotNull Integer anchorInfoId) {
        return this.service.getAllRankInfo(GameLogic.getKey(anchorInfoId), RankingType.GAME_CONTRIBUTION);
    }


    public RankingMessage<Integer> combatEffectiveness(@NotNull Integer anchorInfoId, int s, int t) {
        return new RankingMessage<>(
                RankingType.combatEffectiveness.getValue(),
                this.service.reverseRangeWithScores(GameLogic.getKey(anchorInfoId), RankingType.combatEffectiveness,s,t)
        );
    }

    /// 获得战力排名
    public RankingMessage<Integer> combatEffectiveness(@NotNull Integer anchorInfoId) {
        return new RankingMessage<>(
                RankingType.combatEffectiveness.getValue(),
                this.service.reverseRangeWithScores(GameLogic.getKey(anchorInfoId), RankingType.combatEffectiveness)
        );
    }


    /// 删除榜单
    public void removeAll(Integer anchorInfoId) {
        this.service.removeAll(GameLogic.getKey(anchorInfoId), RankingType.GAME_CONTRIBUTION);
        this.service.removeAll(GameLogic.getKey(anchorInfoId), RankingType.combatEffectiveness);
    }

    /// 清空玩家排名
    public void removeAll(Integer anchorInfoId, Integer userInfoId, String rolesId) {
        this.service.remove(GameLogic.getKey(anchorInfoId), RankingType.GAME_CONTRIBUTION, userInfoId);
        this.service.remove(GameLogic.getKey(anchorInfoId), RankingType.combatEffectiveness, userInfoId);
    }


    /**
     * 排行榜信息
     * @param rankingType
     * @param rankingList
     * @param <T>
     */
    public record RankingMessage<T>(String rankingType, Set<ZSetOperations.TypedTuple<T>> rankingList) {
    }


}
